home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 4 / QRZ Ham Radio Callsign Database - Volume 4.iso / files / dsp / drbubtxt / toolstar.z / toolstar / tools / cldlod.nxt / cldlod.c < prev    next >
C/C++ Source or Header  |  1992-02-21  |  18KB  |  937 lines

  1. /* $Id: cldlod.c,v 1.20 92/02/14 15:55:24 tomc Exp $ */
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #include <signal.h>
  5. #include <time.h>
  6. #include <errno.h>
  7. #if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
  8. #include <stdarg.h>
  9. #else
  10. #include <varargs.h>
  11. #endif
  12. #if !defined ( macintosh )
  13. #include <sys/types.h>
  14. #endif
  15.  
  16.  
  17. /* Headers for working with COFF files */
  18. #include "coreaddr.h"
  19. #include "maout.h"
  20. #include "dspext.h"
  21.  
  22. /* function definitions */
  23. static void onintr();
  24. static void cld_to_lod();
  25. static void read_headers();
  26. static void read_strings();
  27. static void start_record();
  28. static void read_sections();
  29. static void dump_data();
  30.  
  31. #if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
  32. static void eprintf( FILE*, char*, ... );
  33. static void error( char*, ... );
  34. #else
  35. static void eprintf();
  36. static void error();
  37. #endif
  38.  
  39. /*  Global variables  */
  40. FILHDR    file_header;    /* File header structure */
  41. AOUTHDR    opt_header;    /* Optional header structure */
  42. OPTHDR    link_header;    /* Linker header structure */
  43. int    absolute;    /* Absolute file flag */
  44.  
  45. long num_sections;    /* Number of sections */
  46. long section_seek;    /* Used to seek to first section */
  47.  
  48. long symptr;        /* File pointer to symbol table entries */
  49. long num_symbols;    /* Number of symbols */
  50.  
  51. int  data_width;        /* width of data for printing */
  52. int  addr_width;        /* width of address for printing */
  53.  
  54. char *str_tab;        /* Pointer to start of string char. array */
  55. long str_length;    /* Length in bytes of string array */
  56.  
  57. FILE *ifile = NULL;    /* file pointer for input file */
  58. char *ifn = NULL;    /* pointer to input file name */
  59.  
  60. /* init is to non valid memory space */
  61. int  space = 777; /* 0=p, 1=x, 2=y, 3=l, 4=N */
  62.  
  63.  
  64. main (argc, argv)
  65. int argc;
  66. char *argv[];
  67. {
  68.     void exit ();
  69.  
  70.     /* set up for signals, save program name, check for command line options */
  71.     signal (SIGINT, onintr);
  72.  
  73.     /* check for correct command-line */
  74.     if ( argc != 2 )
  75.     {
  76.     fprintf( stderr, "usage: cldlod cldfile > lodfile\n" );
  77.     exit ( -1 );
  78.     }
  79.  
  80.  
  81.     if ( ( ifile = fopen( argv[1], "rb" ) ) == NULL )
  82.     error( "cannot open input file %s", argv[1] );
  83.  
  84.     cld_to_lod();
  85.     
  86.     fclose( ifile );
  87.     exit (0);
  88. }
  89.  
  90.  
  91. static void
  92. cld_to_lod()
  93. {
  94.     read_headers ();
  95.     read_strings ();
  96.  
  97.     /* blow out the _START record */
  98.     if ( symptr != 0  && num_symbols != 0 )    /* no symbols */
  99.     start_record();
  100.     
  101.     read_sections ();
  102.  
  103.     if ( symptr != 0  && num_symbols != 0 )    /* no symbols */
  104.     dump_deb_symbols ();
  105.  
  106.     /* blow out the _END record */
  107.     eprintf( stdout, "\n_END %01.*X\n", addr_width,
  108.         CORE_ADDR_ADDR (opt_header.entry) );
  109. }
  110.  
  111.  
  112. /* blow out the first .cmt symbol with:
  113.         n_sclass == C_NULL
  114.     n_type   == T_NULL
  115. */
  116. static void
  117. start_record()
  118. {
  119.     SYMENT se;
  120.     int i = 0, sym_id = -709;
  121.     
  122.     if ( fseek( ifile, symptr, 0 ) != 0 )
  123.     error ("cannot seek to symbol table");
  124.  
  125.     while ( i < num_symbols )
  126.     {
  127.     if ( freads( (char *)&se, sizeof (SYMENT), 1, ifile ) != 1 )
  128.         error ("cannot read symbol table entry %d", i);
  129. #if !BIG_ENDIAN
  130.     if ( se.n_zeroes )
  131.         swapw( se.n_name, sizeof (long), 2 );
  132. #endif
  133.     if ( strcmp( se.n_name, ".cmt" ) == 0 &&
  134.          se.n_sclass == C_NULL &&
  135.          se.n_type == T_NULL )
  136.     {
  137.         sym_id = CORE_ADDR_ADDR(se.n_value);
  138.         break;
  139.     }
  140.     
  141.     i++;
  142.     }
  143.     
  144.     /* */
  145.     eprintf( stdout, "_START " );
  146.  
  147.     if ( sym_id >= 0 && str_length != 0 )
  148.     {
  149.     char *str_ptr = str_tab;
  150.     int  len;
  151.     long offset = (long) sizeof( str_length );
  152.     
  153.     do
  154.     {
  155.         if ( offset == sym_id )
  156.         break;
  157.         else
  158.         {
  159.         len = strlen( str_ptr );
  160.         offset += len + 1;
  161.         str_ptr += len + 1;
  162.         }
  163.     } while ( str_ptr < ( str_tab + str_length ) );
  164.         
  165.     eprintf( stdout, "%s", str_ptr );
  166.     }
  167.     
  168.     eprintf( stdout, "\n\n" );
  169. }
  170.  
  171.  
  172. static void
  173. read_headers ()
  174. {
  175.     if ( freads( (char *)&file_header, sizeof (FILHDR), 1, ifile ) != 1 )
  176.     error ("cannot read file header");
  177.  
  178.     /* Save the global values */
  179.     num_sections = file_header.f_nscns;
  180.     num_symbols = file_header.f_nsyms;
  181.     symptr = file_header.f_symptr;
  182.     absolute = !!(file_header.f_flags & F_RELFLG);
  183.  
  184.     /* check the MAGIC number */
  185.     if ( file_header.f_magic == M56KMAGIC )
  186.     {
  187.     data_width = 6;
  188.     addr_width = 4;
  189.     }
  190.     else if ( file_header.f_magic == M96KMAGIC )
  191.     {
  192.     data_width = addr_width = 8;
  193.     }
  194.     else if ( file_header.f_magic == M16KMAGIC )
  195.     {
  196.     data_width = addr_width = 4;
  197.     }
  198.     else
  199.     {
  200.     error( "Header has a bad magic number" );
  201.     }
  202.     
  203.  
  204.     /* optional header present */
  205.     if ( file_header.f_opthdr )
  206.     {
  207.     if ( absolute )
  208.     {
  209.         if ( freads( (char *)&opt_header,
  210.             (int)file_header.f_opthdr, 1, ifile ) != 1 )
  211.         error( "cannot read optional file header" );
  212.     }
  213.     else
  214.     {
  215.         if ( freads( (char *)&link_header,
  216.             (int)file_header.f_opthdr, 1, ifile ) != 1 )
  217.         error( "cannot read linker file header" );
  218.     }
  219.     }
  220.  
  221.     /* File offset for first section headers */
  222.     section_seek = sizeof(FILHDR) + file_header.f_opthdr;
  223. }
  224.  
  225.  
  226. static void
  227. read_strings ()
  228. {
  229.     long strings;
  230.  
  231.     strings = symptr + (num_symbols * SYMESZ);
  232.     if ( fseek( ifile, strings, 0 ) != 0 )
  233.     error ( "cannot seek to string table length" );
  234.     if ( freads( (char *)&str_length, 4, 1, ifile ) != 1 && !feof( ifile ))
  235.     error ( "cannot read string table length" );
  236.     if ( feof( ifile ))
  237.     str_length = 0L;
  238.     else if ( str_length )
  239.     {
  240.     str_length -= 4;
  241.     str_tab = (char *)malloc ((unsigned)str_length);
  242.     if ( fseek( ifile, strings + 4, 0 ) != 0 )
  243.         error( "cannot seek to string table" );
  244.     if (fread (str_tab, (int)str_length, 1, ifile) != 1)
  245.         error( "cannot read string table" );
  246.     }
  247. }
  248.  
  249.  
  250. static void
  251. read_sections()
  252. {
  253.     int i;
  254.     XCNHDR sh;        /* Section header structure */
  255.  
  256.     for (i = 0; i < num_sections; i++)
  257.     {
  258.     if (fseek (ifile, section_seek, 0) != 0)
  259.         error ("cannot seek to section headers");
  260.     if (freads ((char *)&sh, sizeof (XCNHDR), 1, ifile) != 1)
  261.         error ("cannot read section headers");
  262. #if !BIG_ENDIAN
  263.     if (sh._n._s_n._s_zeroes)
  264.         swapw (sh._n._s_name, sizeof (long), 2);
  265. #endif
  266.     section_seek += sizeof (XCNHDR);
  267.     
  268.     dump_data (&sh);
  269.     }
  270. }
  271.  
  272.  
  273. char *
  274. get_secname (sh)
  275. XCNHDR *sh;
  276. {
  277.     char *secname;
  278.  
  279.     if ( sh->_n._s_n._s_zeroes )
  280.     secname = sh->_n._s_name;
  281.     else
  282.     {
  283.     if (sh->_n._s_n._s_offset < sizeof (str_length) ||
  284.         sh->_n._s_n._s_offset > str_length)
  285.         error ("invalid string table offset for section header name");
  286.     secname = &str_tab[sh->_n._s_n._s_offset - sizeof (str_length)];
  287.     }
  288.  
  289.     return (secname);
  290. }
  291.  
  292.  
  293. static void
  294. dump_data (sh)
  295. XCNHDR *sh;
  296. {
  297.     char *secname, *get_secname ();
  298.     long *raw_data;
  299.     int  j;
  300.  
  301.     if ( sh->_s.s_scnptr && sh->_s.s_size )
  302.     {
  303.     int memtype = CORE_ADDR_MAP( sh->_s.s_paddr );
  304.     int address  = CORE_ADDR_ADDR( sh->_s.s_paddr );
  305.     char *mem_field;
  306.     
  307.     secname = get_secname( sh );
  308.     
  309.     /* determine the memory field (optional counter ok) */
  310.     switch ( memtype )
  311.     {
  312.     case memory_map_p:
  313.         mem_field = "P";
  314.         break;
  315.         
  316.     case memory_map_pa:
  317.         mem_field = "PA";
  318.         break;
  319.         
  320.     case memory_map_pb:
  321.         mem_field = "PB";
  322.         break;
  323.         
  324.     case memory_map_pe:
  325.         mem_field = "PE";
  326.         break;
  327.         
  328.     case memory_map_pi:
  329.         mem_field = "PI";
  330.         break;
  331.         
  332.     case memory_map_pr:
  333.         mem_field = "PR";
  334.         break;
  335.         
  336.     case memory_map_y:
  337.         mem_field = "Y";
  338.         break;
  339.         
  340.     case memory_map_ya:
  341.         mem_field = "YA";
  342.         break;
  343.         
  344.     case memory_map_yb:
  345.         mem_field = "YB";
  346.         break;
  347.         
  348.     case memory_map_ye:
  349.         mem_field = "YE";
  350.         break;
  351.         
  352.     case memory_map_yi:
  353.         mem_field = "YI";
  354.         break;
  355.         
  356.     case memory_map_yr:
  357.         mem_field = "YR";
  358.         break;
  359.         
  360.     case memory_map_x:
  361.         mem_field = "X";
  362.         break;
  363.         
  364.     case memory_map_xa:
  365.         mem_field = "XA";
  366.         break;
  367.         
  368.     case memory_map_xb:
  369.         mem_field = "XB";
  370.         break;
  371.         
  372.     case memory_map_xe:
  373.         mem_field = "XE";
  374.         break;
  375.         
  376.     case memory_map_xi:
  377.         mem_field = "XI";
  378.         break;
  379.         
  380.     case memory_map_xr:
  381.         mem_field = "XR";
  382.         break;
  383.         
  384.     case memory_map_l:
  385.         mem_field = "L";
  386.         break;
  387.         
  388.     case memory_map_laa:
  389.         mem_field = "LAA";
  390.         break;
  391.         
  392.     case memory_map_lab:
  393.         mem_field = "LAB";
  394.         break;
  395.         
  396.     case memory_map_lba:
  397.         mem_field = "LBA";
  398.         break;
  399.         
  400.     case memory_map_lbb:
  401.         mem_field = "LBB";
  402.         break;
  403.         
  404.     case memory_map_le:
  405.         mem_field = "LE";
  406.         break;
  407.         
  408.     case memory_map_li:
  409.         mem_field = "LI";
  410.         break;
  411.         
  412.     default:
  413.         mem_field = "<ERROR>";
  414.         break;
  415.     }
  416.     
  417.  
  418.     raw_data = (long *)malloc((unsigned)(sh->_s.s_size * sizeof (long)));
  419.  
  420.     if (fseek (ifile, sh->_s.s_scnptr, 0) != 0)
  421.         error ("cannot seek to raw data in section %s", secname);
  422.  
  423.     if (freads ((char *)raw_data, (int)sh->_s.s_size,
  424.             sizeof (long), ifile) != sizeof (long))
  425.         error ("cannot read raw data in section %s",  secname);
  426.  
  427.  
  428.     /* check for block data */
  429.     if ( sh->_s.s_flags & STYP_BLOCK )
  430.     {
  431.         if ( mem_field[0] == 'L' )
  432.         {
  433.         eprintf( stdout, "_BLOCKDATA X %01.*X %01.*X %01.*X\n",
  434.             addr_width, address,
  435.             addr_width, CORE_ADDR_ADDR( sh->_s.s_vaddr ),
  436.             data_width, *raw_data++ );
  437.  
  438.         eprintf( stdout, "_BLOCKDATA Y %01.*X %01.*X %01.*X\n",
  439.             addr_width, address,
  440.             addr_width, CORE_ADDR_ADDR( sh->_s.s_vaddr ),
  441.             data_width, *raw_data++ );
  442.         }
  443.         else
  444.         {
  445.         eprintf( stdout, "_BLOCKDATA %s %01.*X %01.*X %01.*X\n",
  446.             mem_field,
  447.             addr_width, address,
  448.             addr_width, CORE_ADDR_ADDR( sh->_s.s_vaddr ),
  449.             data_width, *raw_data++ );
  450.         }
  451.     }
  452.     
  453.     else
  454.     {
  455.         eprintf (stdout, "_DATA %s %01.*X\n", mem_field,
  456.              addr_width, address );
  457.         
  458.         j = 0;
  459.         while ( j < sh->_s.s_size )
  460.         {
  461.         if ( mem_field[0] == 'L' )
  462.         {
  463.             eprintf (stdout, "%01.*lX %01.*lX ",
  464.                  data_width, *(raw_data+1),
  465.                  data_width, *raw_data);
  466.             raw_data += 2;
  467.             j += 2;
  468.         }
  469.         else
  470.         {
  471.             eprintf (stdout, "%01.*lX ", data_width, *raw_data++);
  472.             j++;
  473.         }
  474.         
  475.  
  476.         if ( j % 8 == 0 && j < sh->_s.s_size )
  477.             eprintf (stdout, "\n");
  478.         }
  479.         eprintf (stdout, "\n");
  480.     }
  481.     }
  482. }
  483.  
  484.  
  485. dump_deb_symbols ()
  486. {
  487.     SYMENT se;
  488.     AUXENT ae;
  489.     int    i, j, k;
  490.  
  491.  
  492.     if (fseek (ifile, symptr, 0) != 0)
  493.     error ("cannot seek to symbol table");
  494.  
  495.     i = 0;
  496.     while (i < num_symbols)
  497.     {
  498.     if (freads ((char *)&se, sizeof (SYMENT), 1, ifile) != 1)
  499.         error ("cannot read symbol table entry %d", i);
  500.  
  501.     dump_se_d (&se); /* ek */
  502.     k = i++;
  503.  
  504.     for (j = 0; j < se.n_numaux; j++)
  505.     {
  506.         if (freads ((char *)&ae, sizeof (AUXENT), 1, ifile) != 1)
  507.         error ("cannot read auxiliary entry %d for symbol entry %d", j, k);
  508.         i++;
  509.     }
  510.     }
  511. }
  512.  
  513.  
  514. dump_se_d (se) /* for debug symbol table */
  515. SYMENT *se;
  516. {
  517.     int  old_space;
  518.     char *name, *type, *sclass;
  519.     char sym_type = 'I';
  520.     
  521.  
  522.     if (se->n_zeroes)
  523.     {
  524. #if !BIG_ENDIAN
  525.     swapw (se->n_name, sizeof (long), 2);
  526. #endif
  527.     name = se->n_name;
  528.     }
  529.     else
  530.     {
  531.     if (se->n_offset < sizeof (str_length) ||
  532.         se->n_offset > str_length)
  533.         error ("invalid string table offset for symbol table entry %d name", se - symptr);
  534.     name = &str_tab[se->n_offset - sizeof (str_length)];
  535.     }
  536.  
  537.     if ( name[0] == '.' )
  538.     {
  539.     return;
  540.     }
  541.  
  542.     switch ( se->n_sclass )
  543.     {
  544.     case C_EFCN:
  545.     sclass = "C_EFCN";
  546.     break;
  547.  
  548.     case C_NULL:
  549.     sclass = "C_NULL";
  550.     break;
  551.  
  552.     case C_AUTO:
  553.     sclass = "C_AUTO";
  554.     break;
  555.  
  556.     case C_EXT:
  557.     sclass = "C_EXT";
  558.     break;
  559.  
  560.     case C_STAT:
  561.     sclass = "C_STAT";
  562.     break;
  563.  
  564.     case C_REG:
  565.     sclass = "C_REG";
  566.     break;
  567.  
  568.     case C_EXTDEF:
  569.     sclass = "C_EXTDEF";
  570.     break;
  571.  
  572.     case C_LABEL:
  573.     sclass = "C_LABEL";
  574.     break;
  575.  
  576.     case C_ULABEL:
  577.     sclass = "C_REG";
  578.     break;
  579.  
  580.     case C_MOS:
  581.     sclass = "C_MOS";
  582.     break;
  583.  
  584.     case C_ARG:
  585.     sclass = "C_ARG";
  586.     break;
  587.  
  588.     case C_STRTAG:
  589.     sclass = "C_STRTAG";
  590.     break;
  591.  
  592.     case C_MOU:
  593.     sclass = "C_MOU";
  594.     break;
  595.  
  596.     case C_UNTAG:
  597.     sclass = "C_UNTAG";
  598.     break;
  599.     
  600.     case C_TPDEF:
  601.     sclass = "C_TPDEF";
  602.     break;
  603.  
  604.     case C_USTATIC:
  605.     sclass = "C_USTATIC";
  606.     break;
  607.  
  608.     case C_ENTAG:
  609.     sclass = "C_ENTAG";
  610.     break;
  611.     
  612.     case C_MOE:
  613.     sclass = "C_MOE";
  614.     break;
  615.  
  616.     case C_REGPARM:
  617.     sclass = "C_REGPARM";
  618.     break;
  619.  
  620.     case C_FIELD:
  621.     sclass = "C_FIELD";
  622.     break;
  623.  
  624.     case C_BLOCK:
  625.     sclass = "C_BLOCK";
  626.     break;
  627.  
  628.     case C_FCN:
  629.     sclass = "C_FCN";
  630.     break;
  631.  
  632.     case C_EOS:
  633.     sclass = "C_EOS";
  634.     break;
  635.  
  636.     case C_FILE:
  637.     sclass = "C_FILE";
  638.     break;
  639.  
  640.     case C_LINE:
  641.     sclass = "C_LINE";
  642.     break;
  643.  
  644.     case C_ALIAS:
  645.     sclass = "C_HIDDEN";
  646.     break;
  647.  
  648.     case C_HIDDEN:
  649.     sclass = "C_HIDDEN";
  650.     break;
  651.  
  652.     default:
  653.     sclass = "<unknown>";
  654.     break;
  655.     }
  656.  
  657.  
  658.     switch ( BTYPE( se->n_type ) )
  659.     {
  660.     case T_NULL:
  661.     type = "T_NULL";
  662.     break;
  663.  
  664.     case T_CHAR:
  665.     type = "T_CHAR";
  666.     break;
  667.  
  668.     case T_SHORT:
  669.     type = "T_SHORT";
  670.     break;
  671.  
  672.     case T_INT:
  673.     type = "T_INT";
  674.     break;
  675.  
  676.     case T_LONG:
  677.     type = "T_LONG";
  678.     break;
  679.  
  680.     case T_FLOAT:
  681.     type = "T_FLOAT";
  682.     sym_type = 'F';
  683.     break;
  684.  
  685.     case T_DOUBLE:
  686.     type = "T_DOUBLE";
  687.     sym_type = 'F';
  688.     break;
  689.     
  690.     case T_STRUCT:
  691.     type = "T_STRUCT";
  692.     break;
  693.  
  694.     case T_UNION:
  695.     type = "T_UNION";
  696.     break;
  697.  
  698.     case T_ENUM:
  699.     type = "T_ENUM";
  700.     break;
  701.  
  702.     case T_MOE:
  703.     type = "T_MOE";
  704.     break;
  705.  
  706.     case T_UCHAR:
  707.     type = "T_UCHAR";
  708.     break;
  709.  
  710.     case T_USHORT:
  711.     type = "T_USHORT";
  712.     break;
  713.  
  714.     case T_UINT:
  715.     type = "T_UINT";
  716.     break;
  717.  
  718.     case T_ULONG:
  719.     type = "T_ULONG";
  720.     break;
  721.  
  722.     default:
  723.     sclass = "<unknown>";
  724.     break;
  725.     }
  726.  
  727.     old_space = space;
  728.     space = CORE_ADDR_MAP ( se->n_value );
  729.  
  730.     switch ( space )
  731.     {
  732.     case memory_map_none:
  733.     if ( old_space != space ) eprintf( stdout, "_SYMBOL N\n" );
  734.  
  735.     /* print symbol name and value */
  736.     eprintf (stdout, "%-19s  %c %01.*lX\n", name, sym_type,
  737.          data_width, CORE_ADDR_ADDR (se->n_value));
  738.     break;
  739.  
  740.     case memory_map_p:
  741.     /* print only pointers to functions (should be ext or stat...) */
  742.     if ( ISFCN (se->n_type) )
  743.     {
  744.         if ( old_space != space ) eprintf(stdout, "_SYMBOL P\n");
  745.     
  746.         /* print symbol name and value */
  747.         eprintf (stdout, "%-19s  I %01.*lX\n", name, 
  748.              data_width, CORE_ADDR_ADDR (se->n_value));
  749.     }
  750.  
  751.     else  /* restore last written space */
  752.         space = old_space;
  753.     break;
  754.  
  755.     case memory_map_x:
  756.     if (old_space != space) eprintf (stdout, "_SYMBOL X\n");
  757.     
  758.     /* print symbol name and value */
  759.     eprintf (stdout, "%-19s  %c %01.*lX\n", name, sym_type,
  760.          data_width, CORE_ADDR_ADDR (se->n_value));
  761.     break;
  762.  
  763.     case memory_map_y:
  764.     if (old_space != space) eprintf (stdout, "_SYMBOL Y\n");
  765.  
  766.     /* print symbol name and value */
  767.     eprintf (stdout, "%-19s  %c %01.*lX\n", name, sym_type,
  768.          data_width, CORE_ADDR_ADDR (se->n_value));
  769.     break;
  770.  
  771.     case memory_map_l:
  772.     if (old_space != space) eprintf (stdout, "_SYMBOL L\n");
  773.  
  774.     /* print symbol name and value */
  775.     eprintf (stdout, "%-19s  %c %01.*lX\n", name, sym_type,
  776.          data_width, CORE_ADDR_ADDR (se->n_value));
  777.     break;
  778.  
  779.     default:
  780.     space = old_space; /* restore last written space */
  781.     return;
  782.     break;
  783.     }
  784. }
  785.  
  786.  
  787. /**
  788. *
  789. * name        freads - swap bytes and read
  790. *
  791. * synopsis    freads (ptr, size, nitems, stream)
  792. *        char *ptr;        pointer to buffer
  793. *        int size;        size of buffer
  794. *        int nitems;        number of items to read
  795. *        FILE *stream;        file pointer
  796. *
  797. * description    Treats ptr as reference to union array; if necessary,
  798. *        swaps bytes to maintain base format byte ordering
  799. *        (big endian).  Calls fread to do I/O.
  800. *
  801. **/
  802. freads (ptr, size, nitems, stream)
  803. char *ptr;
  804. int size, nitems;
  805. FILE *stream;
  806. {
  807.     int rc;
  808.  
  809.     rc = fread (ptr, size, nitems, stream);
  810. #if !BIG_ENDIAN
  811.     swapw (ptr, size, nitems);
  812. #endif
  813.     return (rc);
  814. }
  815.  
  816.  
  817. #if !BIG_ENDIAN
  818.  
  819.  
  820. union wrd
  821. {   /* word union for byte swapping */
  822.     unsigned long l;
  823.     unsigned char b[4];
  824. };
  825.  
  826. /**
  827. *
  828. * name        swapw - swap bytes in words
  829. *
  830. * synopsis    swapw (ptr, size, nitems)
  831. *        char *ptr;        pointer to buffer
  832. *        int size;        size of buffer
  833. *        int nitems;        number of items to write
  834. *
  835. * description    Treats ptr as reference to union array; if necessary,
  836. *        swaps bytes to maintain base format byte ordering
  837. *        (big endian).
  838. *
  839. **/
  840. swapw (ptr, size, nitems)
  841. char *ptr;
  842. int size, nitems;
  843. {
  844.     union wrd *w;
  845.     union wrd *end = (union wrd *)ptr +    ((size * nitems) / sizeof (union wrd));
  846.     unsigned i;
  847.  
  848.     for (w = (union wrd *)ptr; w < end; w++)
  849.     {
  850.     i = w->b[0];
  851.     w->b[0] = w->b[3];
  852.     w->b[3] = i;
  853.     i = w->b[1];
  854.     w->b[1] = w->b[2];
  855.     w->b[2] = i;
  856.     }
  857. }
  858. #endif
  859.  
  860.  
  861. static void
  862. onintr ()            /* clean up from signal */
  863. {
  864.     void exit ();
  865.  
  866.     exit (1);
  867. }
  868.  
  869.  
  870. #ifdef va_dcl
  871. #undef va_dcl
  872. #define va_dcl char *va_alist;
  873. #endif
  874.  
  875. /* VARARGS */
  876.  
  877. /* call fprintf, check for errors */
  878. static void
  879. #if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
  880. eprintf (FILE *fp, char *fmt, ...)
  881. #else
  882. eprintf( va_alist )
  883. va_dcl
  884. #endif
  885. {
  886.     void exit ();
  887.     va_list ap;
  888. #if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
  889.     va_start (ap, fmt);
  890. #else
  891.     FILE *fp;
  892.     char *fmt;
  893.     va_start (ap);
  894.     fp = va_arg (ap, FILE *);
  895.     fmt = va_arg (ap, char *);
  896. #endif
  897.     if (vfprintf (fp, fmt, ap) < 0)
  898.     error ("cannot write to output file");
  899.     va_end (ap);
  900. }
  901.  
  902.  
  903. /* VARARGS */
  904. static void
  905. #if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
  906. error (char *fmt, ...)        /* display error on stderr, exit nonzero */
  907. #else
  908. error (va_alist)        /* display error on stderr, exit nonzero */
  909. va_dcl
  910. #endif
  911. {
  912.     void exit ();
  913.     va_list ap;
  914. #if !LINT
  915.     int err = errno;
  916. #endif
  917. #if defined ( __WATCOMC__ ) || defined( __DGUX__ ) || defined( macintosh )
  918.     va_start (ap, fmt);
  919. #else
  920.     char *fmt;
  921.     va_start (ap);
  922.     fmt = va_arg (ap, char *);
  923. #endif
  924.     fprintf  (stderr, "cldlod: ");
  925.     vfprintf (stderr, fmt, ap);
  926.     fprintf  (stderr, "\n");
  927.     va_end (ap);
  928. #if !LINT
  929.     if (err)
  930.     {
  931.     errno = err;
  932.     perror ( "cldlod" );
  933.     }
  934. #endif
  935.     exit (1);
  936. }
  937.